#include <sys/types.h>
#include <sys/socket.h>
#include "custom_handle.h"

#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/msg.h>
#include <errno.h>
#include <sys/shm.h>
#include "shmem.h"
#include "msg_queue_peer.h"
#include <stdio.h>
#include "cJSON.h"
#include <fcntl.h>
#include <string.h>

#define KB 1024
#define HTML_SIZE (64 * KB)
#define JSON_SIZE (64 * KB)
typedef int BOLL;
//普通的文本回复需要增加html头部
#define HTML_HEAD "Content-Type: text/html\r\n" \
                  "Connection: close\r\n"

//共享内存中存放的节点类型
union val_t {
    int b_val;   //bool类型存储空间
    int i_val;   //整形值存储空间
    float f_val; //浮点值存储空间
};
struct std_node
{
    int key;             //唯一键值
    int type;            //数据点类型
    int dev_type;        //数据点属于哪个设备，根据网关支持的设备自行定义
    union val_t old_val; //变化上报后需要更新旧值
    union val_t new_val; //从共享内存取出最新数据，放到new_val中
    int ret;             //默认为-1，采集成功后设置为0，采集失败再置-1
};

//消息队列的消息结构体
struct msgbuf
{
    long mtype;      // 消息类型，以dev_type区分，1表示stm32,2表示modbus
    char mdata[256]; // 里面是包含key，val的JSON格式的字符串
};
struct msg_node
{
    long mtype;
    char mdata[256];
};
struct msg_node send_message;
static struct shm_param para;
static int *total;
static struct std_node *node_arr;

//创建共享内存有关的宏
#define MAX_NODE 10 //最大支持设备，实际可用是9
#define STD_NODE_LEN sizeof(struct std_node)
#define MAX_NODE_SIZE (MAX_NODE * STD_NODE_LEN) //共享内存的大小

//获取共享内存的数据序列化发送到网页
static int report_json(int sock, const char *input)
{
    int ret = -1;
    ret = shm_init(&para, "shm_test", MAX_NODE_SIZE);
    if (ret < 0)
    {
        return -1;
    }
    void *node_p = shm_getaddr(&para);
    if (node_p == NULL)
    {
        return -1;
    }
    //前4个字节存储设备的数量
    total = (int *)node_p;
    //后面空间存储数据点
    node_arr = (struct std_node *)(node_p + sizeof(int));
    printf("num = %d\n", *total);
    cJSON *root = cJSON_CreateObject();
    cJSON *item = cJSON_CreateArray();
    //循环读共享内存
    for (int i = 0; i < *total; i++)
    {
        cJSON *tmp2 = cJSON_CreateObject();
        cJSON *tmp = cJSON_CreateNumber(node_arr[i].key);
        cJSON_AddItemToObject(tmp2, "key", tmp);
        //判断设备的数据类型再把数据转成字符串，然后添加到new_val中
        if (node_arr[i].type == 1)
        {
            printf("in type1\n");
            char buf[32] = {0};
            sprintf(buf, "%d", node_arr[i].new_val.b_val);
            tmp = cJSON_CreateString(buf);
            cJSON_AddItemToObject(tmp2, "val", tmp);
        }
        else if (node_arr[i].type == 2)
        {
            printf("in type2\n");
            char buf[32] = {0};
            sprintf(buf, "%d", node_arr[i].new_val.i_val);
            tmp = cJSON_CreateString(buf);
            cJSON_AddItemToObject(tmp2, "val", tmp);
        }
        else if (node_arr[i].type == 3)
        {
            printf("in type3\n");
            char buf[32] = {0};
            sprintf(buf, "%.4f", node_arr[i].new_val.f_val);
            tmp = cJSON_CreateString(buf);
            cJSON_AddItemToObject(tmp2, "val", tmp);
        }
        cJSON_AddItemToArray(item, tmp2);
    }

    cJSON_AddItemToObject(root, "data", item);
    //把JSON转成字符串放到
    char *p = cJSON_Print(root);
    // printf("%s\n", p);
    char reply_buf[HTML_SIZE] = {0};
    strcat(reply_buf, p);
    printf("post json_str = %s", reply_buf);
    // fputs(reply_buf, stdout);
    send(sock, reply_buf, strlen(reply_buf), 0);

    free(p);
    cJSON_Delete(root);

    return 0;
}
//modbus排风-开
static int open_paifeng(int sock, const char *input)
{
    int i = 0;
    cJSON *root = NULL;
    cJSON *item1 = NULL;
    cJSON *root1 = NULL; // cjson对象
    printf("led_open:%s\n", input);
    char a[100];
    strcpy(a, input);
    root = cJSON_Parse(a);
    if (root == NULL)
    {
        printf("Error before: [%s]\n", cJSON_GetErrorPtr());
    }
    else
    {
        printf("%d-------------\n", __LINE__);
        cJSON *item1 = cJSON_GetObjectItem(root, "key");
        // printf("%s\n", cJSON_Print(item1));
        int key1 = item1->valueint;

        cJSON *root1 = cJSON_CreateObject();
        cJSON_AddNumberToObject(root1, "key", key1);
        printf("a:%d\n", key1);
        if (key1 == 101 || key1 == 102 || key1 == 103 || key1 == 104)
        {
            printf("%d-------------\n", __LINE__);
            send_message.mtype = 2;
        }
        else
        {
            send_message.mtype = 1;
        }
        item1 = cJSON_GetObjectItem(root, "val");
        cJSON_AddItemToObject(root1, "val", item1);
        cJSON *item_send = cJSON_CreateObject();
        cJSON_AddItemToObject(item_send,"data",root1);

        char *p = cJSON_Print(item_send);
        strcpy(send_message.mdata, p);
        free(p);
        printf("ya = %s\n", send_message.mdata);
    }
    cJSON_Delete(root);
    cJSON_Delete(root1);
    if (msg_queue_send("modbustopic", &send_message, sizeof(send_message), 0) < 0)
    {
        printf("msg_queue_send error\n");
        return -1;
    }
    return 0;
}
//modbus排风-关
static int close_paifeng(int sock, const char *input)
{
    int i = 0;
    cJSON *root = NULL;
    cJSON *item1 = NULL;
    cJSON *root1 = NULL; // cjson对象
    printf("led_open:%s\n", input);
    char a[100];
    strcpy(a, input);
    root = cJSON_Parse(a);
    if (root == NULL)
    {
        printf("Error before: [%s]\n", cJSON_GetErrorPtr());
    }
    else
    {
        printf("%d-------------\n", __LINE__);
        cJSON *item1 = cJSON_GetObjectItem(root, "key");
        // printf("%s\n", cJSON_Print(item1));
        int key1 = item1->valueint;

        cJSON *root1 = cJSON_CreateObject();
        cJSON_AddNumberToObject(root1, "key", key1);
        printf("a:%d\n", key1);
        if (key1 == 101 || key1 == 102 || key1 == 103 || key1 == 104)
        {
            printf("%d-------------\n", __LINE__);
            send_message.mtype = 2;
        }
        else
        {
            send_message.mtype = 1;
        }
        item1 = cJSON_GetObjectItem(root, "val");
        cJSON_AddItemToObject(root1, "val", item1);
        cJSON *item_send = cJSON_CreateObject();
        cJSON_AddItemToObject(item_send,"data",root1);

        char *p = cJSON_Print(item_send);
        strcpy(send_message.mdata, p);
        printf("ya = %s\n", send_message.mdata);
        free(p);
    }
    cJSON_Delete(root);
    cJSON_Delete(root1);
    if (msg_queue_send("modbustopic", &send_message, sizeof(send_message), 0) < 0)
    {
        printf("msg_queue_send error\n");
        return -1;
    }
    return 0;
}
//modbus空气净化器-开
static int open_kongqijinghuaqi(int sock, const char *input)
{
    int i = 0;
    cJSON *root = NULL;
    cJSON *item1 = NULL;
    cJSON *root1 = NULL; // cjson对象
    printf("led_open:%s\n", input);
    char a[100];
    strcpy(a, input);
    root = cJSON_Parse(a);
    if (root == NULL)
    {
        printf("Error before: [%s]\n", cJSON_GetErrorPtr());
    }
    else
    {
        printf("%d-------------\n", __LINE__);
        cJSON *item1 = cJSON_GetObjectItem(root, "key");
        // printf("%s\n", cJSON_Print(item1));
        int key1 = item1->valueint;

        cJSON *root1 = cJSON_CreateObject();
        cJSON_AddNumberToObject(root1, "key", key1);
        printf("a:%d\n", key1);
        if (key1 == 101 || key1 == 102 || key1 == 103 || key1 == 104)
        {
            printf("%d-------------\n", __LINE__);
            send_message.mtype = 2;
        }
        else
        {
            send_message.mtype = 1;
        }
        item1 = cJSON_GetObjectItem(root, "val");
        cJSON_AddItemToObject(root1, "val", item1);
        cJSON *item_send = cJSON_CreateObject();
        cJSON_AddItemToObject(item_send,"data",root1);

        char *p = cJSON_Print(item_send);
        strcpy(send_message.mdata, p);
        free(p);
        printf("ya = %s\n", send_message.mdata);
    }
    cJSON_Delete(root);
    cJSON_Delete(root1);
    if (msg_queue_send("modbustopic", &send_message, sizeof(send_message), 0) < 0)
    {
        printf("msg_queue_send error\n");
        return -1;
    }
    return 0;
}
//modbus空气净化器-关
static int close_kongqijinghuaqi(int sock, const char *input)
{
    int i = 0;
    cJSON *root = NULL;
    cJSON *item1 = NULL;
    cJSON *root1 = NULL; // cjson对象
    printf("led_open:%s\n", input);
    char a[100];
    strcpy(a, input);
    root = cJSON_Parse(a);
    if (root == NULL)
    {
        printf("Error before: [%s]\n", cJSON_GetErrorPtr());
    }
    else
    {
        printf("%d-------------\n", __LINE__);
        cJSON *item1 = cJSON_GetObjectItem(root, "key");
        // printf("%s\n", cJSON_Print(item1));
        int key1 = item1->valueint;

        cJSON *root1 = cJSON_CreateObject();
        cJSON_AddNumberToObject(root1, "key", key1);
        printf("a:%d\n", key1);
        if (key1 == 101 || key1 == 102 || key1 == 103 || key1 == 104)
        {
            printf("%d-------------\n", __LINE__);
            send_message.mtype = 2;
        }
        else
        {
            send_message.mtype = 1;
        }
        item1 = cJSON_GetObjectItem(root, "val");
        cJSON_AddItemToObject(root1, "val", item1);
        cJSON *item_send = cJSON_CreateObject();
        cJSON_AddItemToObject(item_send,"data",root1);

        char *p = cJSON_Print(item_send);
        strcpy(send_message.mdata, p);
        printf("ya = %s\n", send_message.mdata);
        free(p);
    }
    cJSON_Delete(root);
    cJSON_Delete(root1);
    if (msg_queue_send("modbustopic", &send_message, sizeof(send_message), 0) < 0)
    {
        printf("msg_queue_send error\n");
        return -1;
    }
    return 0;
}
//co2检测
static int TVOC(int sock, const char *input)
{
    int i = 0;
    cJSON *root = NULL;
    cJSON *item1 = NULL;
    cJSON *root1 = NULL; // cjson对象
    printf("led_open:%s\n", input);
    char a[100];
    strcpy(a, input);
    root = cJSON_Parse(a);
    if (root == NULL)
    {
        printf("Error before: [%s]\n", cJSON_GetErrorPtr());
    }
    else
    {
        printf("%d-------------\n", __LINE__);
        cJSON *item1 = cJSON_GetObjectItem(root, "key");
        // printf("%s\n", cJSON_Print(item1));
        int key1 = item1->valueint;

        cJSON *root1 = cJSON_CreateObject();
        cJSON_AddNumberToObject(root1, "key", key1);
        printf("a:%d\n", key1);
        if (key1 == 101 || key1 == 102 || key1 == 103 || key1 == 104)
        {
            printf("%d-------------\n", __LINE__);
            send_message.mtype = 2;
        }
        else
        {
            send_message.mtype = 1;
        }
        item1 = cJSON_GetObjectItem(root, "val");
        cJSON_AddItemToObject(root1, "val", item1);
        cJSON *item_send = cJSON_CreateObject();
        cJSON_AddItemToObject(item_send,"data",root1);

        char *p = cJSON_Print(item_send);
        strcpy(send_message.mdata, p);
        printf("ya = %s\n", send_message.mdata);
        free(p);
    }
    cJSON_Delete(root);
    cJSON_Delete(root1);
    if (msg_queue_send("modbustopic", &send_message, sizeof(send_message), 0) < 0)
    {
        printf("msg_queue_send error\n");
        return -1;
    }
    return 0;
}
//甲醛检测
static int Formaldehyde(int sock, const char *input)
{
    int i = 0;
    cJSON *root = NULL;
    cJSON *item1 = NULL;
    cJSON *root1 = NULL; // cjson对象
    printf("led_open:%s\n", input);
    char a[100];
    strcpy(a, input);
    root = cJSON_Parse(a);
    if (root == NULL)
    {
        printf("Error before: [%s]\n", cJSON_GetErrorPtr());
    }
    else
    {
        printf("%d-------------\n", __LINE__);
        cJSON *item1 = cJSON_GetObjectItem(root, "key");
        // printf("%s\n", cJSON_Print(item1));
        int key1 = item1->valueint;

        cJSON *root1 = cJSON_CreateObject();
        cJSON_AddNumberToObject(root1, "key", key1);
        printf("a:%d\n", key1);
        if (key1 == 101 || key1 == 102 || key1 == 103 || key1 == 104)
        {
            printf("%d-------------\n", __LINE__);
            send_message.mtype = 2;
        }
        else
        {
            send_message.mtype = 1;
        }
        item1 = cJSON_GetObjectItem(root, "val");
        cJSON_AddItemToObject(root1, "val", item1);
        cJSON *item_send = cJSON_CreateObject();
        cJSON_AddItemToObject(item_send,"data",root1);

        char *p = cJSON_Print(item_send);
        strcpy(send_message.mdata, p);
        printf("ya = %s\n", send_message.mdata);
    }
    cJSON_Delete(root);
    cJSON_Delete(root1);
    if (msg_queue_send("modbustopic", &send_message, sizeof(send_message), 0) < 0)
    {
        printf("msg_queue_send error\n");
        return -1;
    }
    return 0;
}
//32温度检测
static int temsensor(int sock, const char *input)
{
    int i = 0;
    cJSON *root = NULL;
    cJSON *item1 = NULL;
    cJSON *root1 = NULL; // cjson对象
    printf("led_open:%s\n", input);
    char a[100];
    strcpy(a, input);
    root = cJSON_Parse(a);
    if (root == NULL)
    {
        printf("Error before: [%s]\n", cJSON_GetErrorPtr());
    }
    else
    {
        printf("%d-------------\n", __LINE__);
        cJSON *item1 = cJSON_GetObjectItem(root, "key");
        // printf("%s\n", cJSON_Print(item1));
        int key1 = item1->valueint;

        cJSON *root1 = cJSON_CreateObject();
        cJSON_AddNumberToObject(root1, "key", key1);
        printf("a:%d\n", key1);
        if (key1 == 101 || key1 == 102 || key1 == 103 || key1 == 104)
        {
            printf("%d-------------\n", __LINE__);
            send_message.mtype = 2;
        }
        else
        {
            send_message.mtype = 1;
        }
        item1 = cJSON_GetObjectItem(root, "val");
        cJSON_AddItemToObject(root1, "val", item1);
        cJSON *item_send = cJSON_CreateObject();
        cJSON_AddItemToObject(item_send,"data",root1);

        char *p = cJSON_Print(item_send);
        strcpy(send_message.mdata, p);
        printf("ya = %s\n", send_message.mdata);
        free(p);
    }
    cJSON_Delete(root);
    cJSON_Delete(root1);
    if (msg_queue_send("stm32topic", &send_message, sizeof(send_message), 0) < 0)
    {
        printf("msg_queue_send error\n");
        return -1;
    }
    return 0;
}
//32湿度检测
static int humisensor(int sock, const char *input)
{
    int i = 0;
    cJSON *root = NULL;
    cJSON *item1 = NULL;
    cJSON *root1 = NULL; // cjson对象
    printf("led_open:%s\n", input);
    char a[100];
    strcpy(a, input);
    root = cJSON_Parse(a);
    if (root == NULL)
    {
        printf("Error before: [%s]\n", cJSON_GetErrorPtr());
    }
    else
    {
        printf("%d-------------\n", __LINE__);
        cJSON *item1 = cJSON_GetObjectItem(root, "key");
        // printf("%s\n", cJSON_Print(item1));
        int key1 = item1->valueint;

        cJSON *root1 = cJSON_CreateObject();
        cJSON_AddNumberToObject(root1, "key", key1);
        printf("a:%d\n", key1);
        if (key1 == 101 || key1 == 102 || key1 == 103 || key1 == 104)
        {
            printf("%d-------------\n", __LINE__);
            send_message.mtype = 2;
        }
        else
        {
            send_message.mtype = 1;
        }
        item1 = cJSON_GetObjectItem(root, "val");
        cJSON_AddItemToObject(root1, "val", item1);
        cJSON *item_send = cJSON_CreateObject();
        cJSON_AddItemToObject(item_send,"data",root1);

        char *p = cJSON_Print(item_send);
        strcpy(send_message.mdata, p);
        printf("ya = %s\n", send_message.mdata);
        free(p);
    }
    cJSON_Delete(root);
    cJSON_Delete(root1);
    if (msg_queue_send("stm32topic", &send_message, sizeof(send_message), 0) < 0)
    {
        printf("msg_queue_send error\n");
        return -1;
    }
    return 0;
}
//32电池电量
static int bat(int sock, const char *input)
{
    int i = 0;
    cJSON *root = NULL;
    cJSON *item1 = NULL;
    cJSON *root1 = NULL; // cjson对象
    printf("led_open:%s\n", input);
    char a[100];
    strcpy(a, input);
    root = cJSON_Parse(a);
    if (root == NULL)
    {
        printf("Error before: [%s]\n", cJSON_GetErrorPtr());
    }
    else
    {
        printf("%d-------------\n", __LINE__);
        cJSON *item1 = cJSON_GetObjectItem(root, "key");
        // printf("%s\n", cJSON_Print(item1));
        int key1 = item1->valueint;

        cJSON *root1 = cJSON_CreateObject();
        cJSON_AddNumberToObject(root1, "key", key1);
        printf("a:%d\n", key1);
        if (key1 == 101 || key1 == 102 || key1 == 103 || key1 == 104)
        {
            printf("%d-------------\n", __LINE__);
            send_message.mtype = 2;
        }
        else
        {
            send_message.mtype = 1;
        }
        item1 = cJSON_GetObjectItem(root, "val");
        cJSON_AddItemToObject(root1, "val", item1);
        cJSON *item_send = cJSON_CreateObject();
        cJSON_AddItemToObject(item_send,"data",root1);

        char *p = cJSON_Print(item_send);
        strcpy(send_message.mdata, p);
        printf("ya = %s\n", send_message.mdata);
        free(p);
    }
    cJSON_Delete(root);
    cJSON_Delete(root1);
    if (msg_queue_send("stm32topic", &send_message, sizeof(send_message), 0) < 0)
    {
        printf("msg_queue_send error\n");
        return -1;
    }
    return 0;
}
//stm32灯-开
static int stm32open_light(int sock, const char *input)
{
    int i = 0;
    cJSON *root = NULL;
    cJSON *item1 = NULL;
    cJSON *root1 = NULL; // cjson对象

    char a[100];
    strcpy(a, input);
    root = cJSON_Parse(a);
    if (root == NULL)
    {
        printf("Error before: [%s]\n", cJSON_GetErrorPtr());
    }
    else
    {
        printf("%d-------------\n", __LINE__);
        cJSON *item1 = cJSON_GetObjectItem(root, "key");
        // printf("%s\n", cJSON_Print(item1));
        int key1 = item1->valueint;

        cJSON *root1 = cJSON_CreateObject();
        cJSON_AddNumberToObject(root1, "key", key1);
        printf("a:%d\n", key1);
        if (key1 == 3011 || key1 == 3012 || key1 == 302|| key1 == 303)
        {
            printf("%d-------------\n", __LINE__);
            send_message.mtype = 1;
        }
        else
        {
            send_message.mtype = 2;
        }
        item1 = cJSON_GetObjectItem(root, "val");
        cJSON_AddItemToObject(root1, "val", item1);
        cJSON *item_send = cJSON_CreateObject();
        cJSON_AddItemToObject(item_send,"data",root1);

        char *p = cJSON_Print(item_send);
        strcpy(send_message.mdata, p);
        printf("ya = %s\n", send_message.mdata);
        free(p);
    }
    cJSON_Delete(root);
    cJSON_Delete(root1);
    if (msg_queue_send("stm32topic", &send_message, sizeof(send_message), 0) < 0)
    {
        printf("msg_queue_send error\n");
        return -1;
    }
    return 0;
}
//stm32灯-关
static int stm32close_light(int sock, const char *input)
{
    printf("================================\n");
    int i = 0;
    cJSON *root = NULL;
    cJSON *item1 = NULL;
    cJSON *root1 = NULL; // cjson对象
    printf("led_open:%s\n", input);
    char a[100];
    strcpy(a, input);
    root = cJSON_Parse(a);
    if (root == NULL)
    {
        printf("Error before: [%s]\n", cJSON_GetErrorPtr());
    }
    else
    {
        printf("%d-------------\n", __LINE__);
        cJSON *item1 = cJSON_GetObjectItem(root, "key");
        // printf("%s\n", cJSON_Print(item1));
        int key1 = item1->valueint;

        cJSON *root1 = cJSON_CreateObject();
        cJSON_AddNumberToObject(root1, "key", key1);
        printf("a:%d\n", key1);
        if (key1 == 3011 || key1 == 3012 || key1 == 302|| key1 == 303)
        {
            printf("%d-------------\n", __LINE__);
            send_message.mtype = 1;
        }
        else
        {
            send_message.mtype = 2;
        }
        item1 = cJSON_GetObjectItem(root, "val");
        cJSON_AddItemToObject(root1, "val", item1);
        cJSON *item_send = cJSON_CreateObject();
        cJSON_AddItemToObject(item_send,"data",root1);

        char *p = cJSON_Print(item_send);
        strcpy(send_message.mdata, p);
        printf("ya = %s\n", send_message.mdata);
        free(p);
    }
    cJSON_Delete(root);
    cJSON_Delete(root1);
    if (msg_queue_send("stm32topic", &send_message, sizeof(send_message), 0) < 0)
    {
        printf("msg_queue_send error\n");
        return -1;
    }
    return 0;
}
/**
 * @brief 处理自定义请求，在这里添加进程通信
 * @param input
 * @return
 */
int parse_and_process(int sock, const char *query_string, const char *input)
{
    printf("%s\n",input);
    //query_string不一定能用的到
    if (strstr(input, "type") && strstr(input, "limit"))
    {
        return report_json(sock, input);
    }
    else if (strstr(input, "\"key\":103") && strstr(input, "\"val\":\"1\"")) // 注意val对应值为字符串类型
    {
        return open_paifeng(sock, input);
    }
    else if (strstr(input, "\"key\":103") && strstr(input, "\"val\":\"0\""))
    {
        return close_paifeng(sock, input);
    }
    else if (strstr(input, "\"key\":104") && strstr(input, "\"val\":\"1\""))
    {
        return open_kongqijinghuaqi(sock, input);
    }
    else if (strstr(input, "\"key\":104") && strstr(input, "\"val\":\"0\""))
    {
        return close_kongqijinghuaqi(sock, input);
    }
    else if (strstr(input, "\"key\":102"))
    {
        return TVOC(sock, input);
    }
    else if (strstr(input, "\"key\":101"))
    {
        return Formaldehyde(sock, input);
    }
    else if (strstr(input, "\"key\":3011"))
    {
        return temsensor(sock, input);
    }
    else if (strstr(input, "\"key\":3012"))
    {
        return humisensor(sock, input);
    }
    else if (strstr(input, "\"key\":302"))
    {
        return bat(sock, input);
    }
    else if (strstr(input, "\"key\":303") && strstr(input, "\"val\":\"1\""))
    {
        return stm32open_light(sock, input);
    }
    else if (strstr(input, "\"key\":303") && strstr(input, "\"val\":\"0\""))
    {
        return stm32close_light(sock, input);
    }
    else //剩下的都是json请求，这个和协议有关了
    {
        // 构建要回复的JSON数据
        const char *json_response = "{\"message\": \"Hello, client!\"}";

        // 发送HTTP响应给客户端
        send(sock, json_response, strlen(json_response), 0);
    }

    return 0;
}